﻿// <copyright file="EnumUtil.cs" company="Lu Studio">
// Copyright (c) Lu Studio. All rights reserved.
// </copyright>
// <author>lu qi</author>
// <createTime>2021-06-26</createTime>
namespace ElfKit.Common
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Reflection;

    /// <summary>
    /// <see cref="Enum"/>工具类.
    /// </summary>
    public static class EnumUtil
    {
        /// <summary>
        /// 获得<paramref name="enumType"/>枚举类型的值与描述映射.
        /// </summary>
        /// <param name="enumType"><see cref="Type"/>类型.</param>
        /// <returns>值与描述映射</returns>
        /// <exception cref="ArgumentException"><paramref name="enumType"/> is not enum type.</exception>
        public static ReadOnlyDictionary<long, string> GetValueToDescriptionMap(Type enumType)
        {
            Guard.IsEnum(enumType, nameof(enumType));
            
            return InternalCache.Get(
                () => InternalCache.GetKey(enumType, nameof(GetValueToDescriptionMap)),
                () => CreateValueToDescriptionMap(enumType),
                InternalCache.Policy.Permanent());
        }

        #region 内部函数

        /// <summary>
        /// 创建枚举值与描述映射.
        /// </summary>
        /// <param name="enumType"><see cref="Type"/>枚举类型.</param>
        /// <returns>枚举值与描述映射.</returns>
        private static ReadOnlyDictionary<long, string> CreateValueToDescriptionMap(Type enumType)
        {
            Dictionary<long, string> map = new Dictionary<long, string>();
            foreach (FieldInfo fi in enumType.GetFields(Constant.BindingAttributes.StaticPublic))
            {
                ResourceAttribute attr = fi.GetCustomAttribute<ResourceAttribute>();
                if (attr != null)
                {
                    long value = Convert.ToInt64(fi.GetValue(null));
                    string description = Localization.GetString(attr);
                    map.Add(value, description);
                }
            }

            return new ReadOnlyDictionary<long, string>(map);
        }

        #endregion
    }
}